Skip to content

fix: rebuild Contact from public_address after 401 NAT challenge#107

Merged
shenjinti merged 1 commit intorestsend:mainfrom
bevenky:fix/registration-contact-nat-401
Mar 31, 2026
Merged

fix: rebuild Contact from public_address after 401 NAT challenge#107
shenjinti merged 1 commit intorestsend:mainfrom
bevenky:fix/registration-contact-nat-401

Conversation

@bevenky
Copy link
Copy Markdown
Contributor

@bevenky bevenky commented Mar 29, 2026

Summary

After a 401 Unauthorized response, the Via rport/received parameters reveal the actual NAT-mapped source port, which may differ from the STUN-discovered port. The auth retry reused the original Contact with the stale port, causing registration to succeed but incoming requests to be routed to the wrong address.

  • Rebuild Contact header from updated public_address after handle_client_authenticate, so the retry uses the server-observed NAT mapping
  • Remove duplicate rport push in handle_client_authenticateget_via already adds it, and duplicate Via params cause some servers to silently drop the request

Problem

  1. Client discovers public_ip:60537 via STUN, sends REGISTER with Contact: <sip:user@public_ip:60537>
  2. Server responds 401, Via header shows rport=16358;received=public_ip (actual source port differs from STUN)
  3. public_address is updated to public_ip:16358, but the auth retry clones the original request, keeping the stale Contact public_ip:60537
  4. Registration succeeds, but incoming INVITEs are routed to port 60537 instead of 16358

Fix

After handle_client_authenticate returns the auth response, check if public_address was updated and rebuild the Contact header with the corrected address before sending.

Test plan

  • Existing tests pass
  • Verified with live SIP registration behind NAT — Contact in auth retry matches rport from 401

After a 401 Unauthorized response, the Via rport/received parameters
reveal the actual NAT-mapped source port, which may differ from the
STUN-discovered port. The auth retry reused the original Contact with
the stale port, causing registration to succeed but incoming requests
to be routed to the wrong address.

Now rebuilds the Contact header from the updated public_address after
handle_client_authenticate, ensuring the retry uses the correct NAT
mapping observed by the server.

Also removes a duplicate rport push in handle_client_authenticate —
get_via already adds rport, and duplicate Via params can cause some
servers to silently drop the request.
@shenjinti shenjinti merged commit c6663d9 into restsend:main Mar 31, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants